<template>
  <div>
    <!-- 搜索 -->
    <my-search v-if="hasSearch" :search-data="searchData" @search="onSearch" />
    <!-- 按钮操作 -->
    <div v-if="heardOperation" class="heardOptBox">
      <el-button
        v-for="item in heardOperation"
        :key="item.name"
        type="primary"
        size="small"
        style="margin-bottom: 20px"
        @click="handlerHeardOperation(item)"
      >{{ item.title }}</el-button>
      <div class="right">
        <slot name="right" />
      </div>
    </div>
    <!-- 表格 -->
    <el-table
      v-loading="loading"
      :row-key="row => row.id"
      :data="tableData"
      style="width: 100%"
      :header-cell-style="{ backgroundColor: '#f4f6f8' }"
      @selection-change="handleSelectionChange"
    >
      <!-- select列 -->
      <el-table-column
        v-if="hasSelect"
        type="selection"
        width="55"
      />
      <!-- 序号列 -->
      <el-table-column type="index" label="序号" width="50" :index="index" />
      <!-- 其他列 -->
      <el-table-column
        v-for="column in columns"
        :key="column.prop"
        :prop="column.prop"
        :label="column.label"
      >
        <template slot-scope="scope">
          <!-- 自定义列 -->
          <div v-if="column.custom">
            <slot :name="column.prop" :row="scope.row" />
          </div>
          <!--默认显示内容 -->
          <div v-else>
            {{ scope.row[column.prop] }}
          </div>
          <!-- 操作列 -->
          <template
            v-if="column.operations"
          >
            <el-button
              v-for="operation in column.operations"
              :key="operation.label"
              type="text"
              @click="handleOperation(operation.handler, scope.row)"
            >
              {{ operation.label }}
            </el-button>
          </template>
        </template>
      </el-table-column>
      <!-- 表格空状态 -->
      <template slot="empty">
        <img
          src="../assets/empty.svg"
          alt
          style="
            margin: 120px auto 8px auto;
            height: 50;
            width: 78px;
            display: block;
          "
        >
        <p style="line-height: 22px; font-size: 14px; margin-bottom: 60px">
          暂无数据
        </p>
      </template>
    </el-table>
    <!-- 分页器 -->
    <my-pagination
      :total="total"
      @change="
        (val) => {
          handlerPageChange(val);
        }
      "
    />
    <!-- 弹框 -->
    <my-dialog
      :visible.sync="visible"
      :form-option-items="formOptionItems"
      :handler-submit="handlerSubmit"
      :only-read-form-items="onlyReadFormItems"
      @onFormSubmit="onSubmit"
    />
  </div>
</template>

<script>
import MyPagination from '@/components/my-pagination'
import request from '@/utils/request'
import { onSecondConfirm } from '@/utils'
import MySearch from '@/components/my-search'
import MyDialog from '@/components/my-dialog'
import router from '@/router'

export default {
  components: {
    MyPagination,
    MySearch,
    MyDialog
  },
  props: {
    columns: Array, // 表格列配置
    actionUrl: String, // 请求表格数据的路径
    hasSearch: Boolean, // 是否配置搜索功能
    searchData: Array, // 搜索数据配置
    heardOperation: Array, // 添加、批量删除表格数据的头部按钮配置
    formOptionItems: Array, // 添加/编辑的表单项配置
    onlyReadFormItems: Array, // 查看表单的配置项
    hasSelect: Boolean // 是否配置多选项

  },
  data() {
    return {
      visible: false,
      tableData: [],
      total: 0,
      loading: false,
      handlerSubmit: {}, // 表单提交配置项
      pageParams: {
        page: 1,
        pageSize: 10
      },
      multipleSelection: []
    }
  },
  computed: {
    index() {
      return this.pageParams.page > 1
        ? (this.pageParams.page - 1) * this.pageParams.pageSize + 1
        : 1
    }
  },
  watch: {
    actionUrl() {
      this.getList(this.pageParams)
    }
  },
  created() {
    this.getList(this.pageParams)
  },
  methods: {
    // 获取表格数据
    async getList(params) {
      this.loading = true
      const res = await request({
        url: this.actionUrl,
        params
      })
      this.tableData = res.rows
      this.total = res.total
      if (!this.total) {
        this.pageParams.page = 1
      }
      this.loading = false
    },
    // 分页改变操作
    async handlerPageChange(val) {
      // 更新参数 刷新数据
      this.pageParams = val
      this.getList(this.pageParams)
    },
    // 表格行内操作
    handleOperation(operation, row) {
      operation.name === 'delete' && this.onDelById(operation, row)

      if (!operation.path) {
        // 走弹窗
        if (operation.name === 'edit') {
        // 编辑
          this.visible = true
          this.handlerSubmit = { name: 'edit', url: operation.url, detailUrl: operation.detailUrl + '/' + row.id }
        } else if (operation.name === 'read') {
        // 查看
          this.visible = true
          this.handlerSubmit = { name: 'read', detailUrl: operation.detailUrl + '/' + row.id }
        }
      } else {
        // 走二级路由
        router.push(operation.path + row.id)
      }
    },
    // 表格外的按钮操作
    handlerHeardOperation(item) {
      if (!item.handler.path) {
        // 走弹出框
        if (item.name === 'add') {
          this.visible = true
          this.handlerSubmit = { name: 'add', url: item.handler.url }
        } else if (item.name === 'delete') {
          // 走批量删除操作
          this.onDelAll(item.handler.url)
        }
      } else {
        // 走二级路由
        router.push(item.handler.path)
      }
    },
    // 行内删除
    onDelById(operation, row) {
      // 二次确认
      onSecondConfirm({
        content: operation.title,
        handler: async() => {
          await request({
            url: operation.url + '/' + row.id,
            method: 'delete'
          })
          this.$message.success('删除成功!')
          this.getList()
        }
      })
    },
    // 批量删除
    async onDelAll(url) {
      if (this.multipleSelection.length === 0) {
        this.$message.warning('请选择要删除的行')
        return
      }
      // 筛选id出来
      const ids = this.multipleSelection.map(item => item.id).join(',')
      // 发请求
      await request({
        url: url + '/' + ids,
        method: 'delete'
      })
      // 提示用户请求成功
      this.$message.success('批量删除成功')
      this.getList()
    },
    // 搜索执行
    onSearch(val) {
      const params = Object.assign(this.pageParams, val)
      this.getList(params)
    },
    // 表格提交执行
    onSubmit() {
      // 刷新列表
      this.getList()
    },
    handleSelectionChange(val) {
      this.multipleSelection = val
    }
  }
  // 其他方法...
}
</script>
<style lang="scss" scoped>
.heardOptBox{
  display: flex;
  width: 100%;
  position: relative;
}
.right{
  position: absolute;
  right: 10px;

}
</style>
